package edu.zqu.collegeField.project.service.impl;


import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.zqu.collegeField.common.utils.BeanMapper;
import edu.zqu.collegeField.framework.easyexcel.model.FieldModel;
import edu.zqu.collegeField.framework.openfeign.api.GetCollegeNameApi;
import edu.zqu.collegeField.project.mapper.AreaMapper;
import edu.zqu.collegeField.project.mapper.FieldTypeMapper;
import edu.zqu.collegeField.project.mapper.SchoolMapper;
import edu.zqu.collegeField.project.po.Field;
import edu.zqu.collegeField.project.mapper.FieldMapper;
import edu.zqu.collegeField.project.service.AreaService;
import edu.zqu.collegeField.project.service.FieldService;
import edu.zqu.collegeField.project.service.FieldTypeService;
import edu.zqu.collegeField.project.service.SchoolService;
import edu.zqu.collegeField.project.vo.FieldVo;
import edu.zqu.common.core.text.Convert;
import edu.zqu.common.utils.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 场地 服务实现类
 * </p>
 *
 * @author 廖森
 * @since 2020-06-28
 */
@Service
public class FieldServiceImpl extends ServiceImpl<FieldMapper, Field> implements FieldService {
    @Autowired
    private FieldMapper fieldMapper;
    @Autowired
    private SchoolService schoolService;
    @Autowired
    private FieldTypeService fieldTypeService;
    @Autowired
    private AreaService areaService;
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    @Autowired
    private GetCollegeNameApi getCollegeNameApi;

    @Override
    public List<FieldVo> get(BigInteger collegeId, //获取场地列表s
                             String name,
                             Integer fieldTypeId,
                             BigInteger schoolId,
                             BigInteger areaId) {
        HashMap<String, String> map = new HashMap<>();
        map.put("collegeId", Convert.toStr(collegeId));
        map.put("fieldTypeId", Convert.toStr(fieldTypeId));
        map.put("schoolId", Convert.toStr(schoolId));
        map.put("areaId", Convert.toStr(areaId));
        map.put("name", name);
        List<FieldVo> fieldVoList = BeanMapper.mapList(fieldMapper.get(map), FieldVo.class);
        String collegeName = getCollegeNameApi.getCollegeName(collegeId);
        for (FieldVo fieldVo : fieldVoList) {
            fieldVo.setCollegeName(collegeName);
        }
        return fieldVoList;
    }

    @Override
    public FieldVo getById(BigInteger id) {//获取场地
        HashMap<String, String> map = new HashMap<>();
        map.put("id", Convert.toStr(id));
        FieldVo fieldVo = BeanMapper.map(fieldMapper.getById(map), FieldVo.class);
        String collegeName = getCollegeNameApi.getCollegeName(fieldVo.getCollegeId());
        fieldVo.setCollegeName(collegeName);
        return fieldVo;
    }

    @Override
    public String getNameById(BigInteger id) {
        HashMap<String, String> map = new HashMap<>();
        map.put("id", Convert.toStr(id));
        return fieldMapper.getNameById(map);
    }

    @Override
    public int add(Field field) {//添加场地
        field.setId(null).setDeleted(null).setUpdateTime(new Timestamp(System.currentTimeMillis()));
        return fieldMapper.insert(field);
    }

    @Transactional(rollbackFor = MybatisPlusException.class)
    @Override
    public int update(Field fieldUpdate) {//更新场地信息
        Field field = fieldMapper.selectById(fieldUpdate.getId());
        if (StringUtils.isNull(field)) {
            throw new NullPointerException("找不到该场地");
        }
        BeanMapper.copyPropertiesNotNull(fieldUpdate, field);
        try {
            int insert = fieldMapper.insert(field.setLastVersion(fieldUpdate.getId()));
            if (insert >= 1) {
                return delete(fieldUpdate.getId(), fieldUpdate.getByWho());
            }
        } catch (Throwable e) {
            throw new MybatisPlusException("更新失败");
        }
        return 0;
    }

    @Transactional(rollbackFor = MybatisPlusException.class)
    @Override
    public int delete(BigInteger id, BigInteger byWho) {//删除场地信息
        try {
            UpdateWrapper<Field> fieldUpdateWrapper = new UpdateWrapper<Field>().eq("id", Convert.toStr(id));
            int update = fieldMapper.update(new Field().setByWho(byWho), fieldUpdateWrapper);
            if (update >= 1) {
                return fieldMapper.delete(fieldUpdateWrapper);
            }
        } catch (Throwable e) {
            throw new MybatisPlusException("删除失败");
        }
        return 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean insertBatch(List<FieldModel> fieldModelList, BigInteger collegeId, BigInteger byWho) {
        for (FieldModel fieldModel : fieldModelList) {
            BigInteger schoolId = schoolService.getByName(collegeId, fieldModel.getSchoolName()).getId();
            Integer fieldTypeId = fieldTypeService.getByName(collegeId, fieldModel.getFieldTypeName()).getId();
            BigInteger areaId = areaService.getByName(collegeId, fieldModel.getAreaName()).getId();
            if (StringUtils.isNull(schoolId)) {
                throw new NullPointerException("找不到名为" + fieldModel.getSchoolName() + "的校区");
            }
            if (StringUtils.isNull(fieldTypeId)) {
                throw new NullPointerException("找不到名为" + fieldModel.getFieldTypeName() + "的场地类型");
            }
            if (StringUtils.isNull(areaId)) {
                throw new NullPointerException("找不到名为" + fieldModel.getAreaName() + "的功能区");
            }
            fieldModel.setCollegeId(collegeId);
            fieldModel.setSchoolId(schoolId);
            fieldModel.setFieldTypeId(fieldTypeId);
            fieldModel.setAreaId(areaId);
            fieldModel.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            fieldModel.setByWho(byWho);
        }
        List<Field> fieldList = BeanMapper.mapList(fieldModelList, Field.class);
        if (CollectionUtils.isEmpty(fieldList)) {
            throw new IllegalArgumentException("Error: Excel的有效数据不为空");
        }
        try (SqlSession batchSqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
            int size = fieldList.size();
            String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);
            for (int i = 0; i < size; i++) {
                batchSqlSession.insert(sqlStatement, fieldList.get(i));
                if (i >= 1) {
                    batchSqlSession.flushStatements();
                }
            }
            batchSqlSession.flushStatements();
        } catch (Throwable e) {
            throw new MybatisPlusException("Error：批量插入失败", e);
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean insertBatch(List<T> entityList, int batchSize) {
        if (CollectionUtils.isEmpty(entityList)) {
            throw new IllegalArgumentException("Error: Excel的有效数据不为空");
        }
        try (SqlSession batchSqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
            int size = entityList.size();
            String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);
            for (int i = 0; i < size; i++) {
                batchSqlSession.insert(sqlStatement, entityList.get(i));
                if (i >= 1 && i % batchSize == 0) {
                    batchSqlSession.flushStatements();
                }
            }
            batchSqlSession.flushStatements();
        } catch (Throwable e) {
            throw new MybatisPlusException("Error：批量插入失败", e);
        }
        return true;
    }
}
